﻿using ETask.Api.Data;
using ETask.Api.Dtos;
using ETask.Api.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;

namespace ETask.Api.Repositories
{
    public class ProjectRepository : Repository<Project>, IProjectRepository
    {
        public ProjectRepository(AppDbContext context) : base(context)
        {
        }

        public async Task<int> AddUserListAsync(List<ProjectMember> list)
        {
            await _context.ProjectMembers.AddRangeAsync(list);
            int rows = _context.SaveChanges();
            return rows;
        }

        public async Task<bool> CheckMemberExists(int projectId, int userId)
        {
            bool exist = await _context.ProjectMembers.AnyAsync(q => q.UserId == userId && q.ProjectId == projectId);
            return exist;
        }

        public async Task<int> DelProjectUserById(int id)
        {
            int rows = await _context.ProjectMembers.Where(q => q.Id == id).ExecuteDeleteAsync();
            return rows;
        }

        public async Task<PagedResult<ProjectDto>> GetListAsync(ProjectListParams listParams)
        {
            try
            {
                var projectQuery = _context.Projects.AsQueryable();
                if (!string.IsNullOrWhiteSpace(listParams.KeyWord))
                {
                    projectQuery = projectQuery.Where(q => q.Name.Contains(listParams.KeyWord));
                }
                if (listParams.Status.HasValue)
                {
                    projectQuery = projectQuery.Where(q => q.Status == listParams.Status.Value);
                }
                if (listParams.BeginTime.HasValue)
                {
                    projectQuery = projectQuery.Where(q => q.StartDate >= listParams.BeginTime.Value);
                }
                if (listParams.EndTime.HasValue)
                {
                    projectQuery = projectQuery.Where(q => q.StartDate <= listParams.EndTime.Value);
                }

                // 获取筛选后的项目ID列表
                var filteredProjectIds = await projectQuery.Select(p => p.Id).ToListAsync();

                // 使用GroupJoin查询项目及其成员信息
                var query = _context.Projects
                    .Where(p => filteredProjectIds.Contains(p.Id))
                    .GroupJoin(_context.ProjectMembers, 
                        project => project.Id, 
                        member => member.ProjectId,
                        (project, members) => new { Project = project, Members = members })
                    .SelectMany(x => x.Members.DefaultIfEmpty(),
                        (x, member) => new { x.Project, Member = member })
                    .GroupJoin(_context.Users, 
                        pm => pm.Member != null ? pm.Member.UserId : (int?)null, 
                        user => user.Id,
                        (pm, users) => new { pm.Project, pm.Member, Users = users })
                    .SelectMany(x => x.Users.DefaultIfEmpty(),
                        (x, user) => new { x.Project, x.Member, User = user })
                    .GroupBy(dto => dto.Project.Id)
                    .Select(g => new ProjectDto
                    {
                        Id = g.Key,
                        Name = g.First().Project.Name,
                        Status = g.First().Project.Status,
                        StartDate = g.First().Project.StartDate,
                        EndDate = g.First().Project.EndDate,
                        Description = g.First().Project.Description,
                        CreatedAt = g.First().Project.CreatedAt,
                        UpdatedAt = g.First().Project.UpdatedAt,
                        Members = g.Where(m => m.Member != null && m.User != null)
                             .Select(q => new ProjectMemberDto
                             {
                                 Id = q.Member.Id,
                                 UserId = q.User.Id,
                                 Name = q.User.Name ?? "未知用户",
                                 Account = q.User.Account,
                                 Role = q.Member.Role
                             }).ToList()
                    })
                    .OrderByDescending(p => p.CreatedAt);

                return await query.ToPagedResultAsync(listParams.PageDto);
            }
            catch (Exception ex)
            {
                return new PagedResult<ProjectDto>
                {
                    Items = new List<ProjectDto>(),
                    TotalCount = 0,
                    TotalPages = 0,
                    CurrentPage = listParams.PageDto.PageNumber,
                    PageSize = listParams.PageDto.PageSize
                };
            }
        }

        public async Task<ProjectMember> GetMemberById(int id)
        {
            ProjectMember member = await _context.ProjectMembers.FindAsync(id);
            return member;
        }

        public async Task<List<ProjectMemberDto>> GetProjectMembers(int projectId)
        {
            var query = _context.ProjectMembers
                .Where(member => member.ProjectId == projectId)
                .GroupJoin(
                    _context.Users,
                    member => member.UserId,
                    user => user.Id,
                    (member, users) => new { member, users }
                )
                .SelectMany(
                    x => x.users.DefaultIfEmpty(),
                    (x, user) => new { x.member, user }
                )
                .GroupJoin(
                    _context.Depts,
                    x => x.user != null ? x.user.DeptCode : null,
                    dept => dept.DeptCode,
                    (x, depts) => new { x.member, x.user, depts }
                )
                .SelectMany(
                    x => x.depts.DefaultIfEmpty(),
                    (x, dept) => new { x.member, x.user, dept }
                )
                .OrderByDescending(x => x.member.CreatedAt);

            var list = await query.Select(x => new ProjectMemberDto
            {
                Id = x.member.Id,
                UserId = x.member.UserId,
                Name = x.user != null ? x.user.Name : "未知用户",
                Account = x.user != null ? x.user.Account : "",
                DeptName = x.dept != null ? x.dept.DeptName : "",
                Phone = x.user != null ? x.user.Phone : "",
                Email = x.user != null ? x.user.Email : "",
                Role = x.member.Role,
                CreatedAt = x.member.CreatedAt,
                ProjectId = x.member.ProjectId
            }).ToListAsync();
            
            return list;
        }

        public async Task<int> UpdateProjectUser(ProjectMember member)
        {
            _context.ProjectMembers.Update(member);
            return await _context.SaveChangesAsync();
        }
    }
}
